package com.smartao.base.menu;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.smartao.core.dao.BaseEntityDao;

@Repository
public class MenuDaoImpl extends BaseEntityDao<Menu, Long> implements MenuDao{

	/**
	 * 查询指定类型的所有菜单
	 */
	@Override
	public List<Menu> findByMenutype(MenuType menutype) {
		return findBy("menutype", menutype);
	}

	@Override
	public void save(Menu menu) {
		// 新增menu情况下需更新父菜单的childCount;
		if(menu.getId()==null && menu.getParent()!=null){
			String hqlUpdateChildCount = "UPDATE Menu SET  CHILD_COUNT = CHILD_COUNT + 1 WHERE ID = :pid";
			getSession().createQuery(hqlUpdateChildCount).setLong("pid", menu.getParent().getId()).executeUpdate();
		}
		super.save(menu);
		
	}
	
	@Override
	public void delete(Menu menu) {
		// 删除菜单需更新父菜单的childCount;
		if(menu.getParent()!=null){
			String hqlUpdateChildCount = "UPDATE Menu SET  CHILD_COUNT = CHILD_COUNT - 1 WHERE ID = :pid";
			getSession().createQuery(hqlUpdateChildCount).setLong("pid", menu.getParent().getId()).executeUpdate();
		}
		// TODO: 删除该菜单的子菜单，此处递归，可否有更好的方法，或设计 ;
		List<Menu> allChildren = new ArrayList<Menu>();
		findAllChildren(menu.getId(), menu.getMenutype(), allChildren);
		StringBuffer sb = new StringBuffer();
		sb.append("DELETE FROM Menu where id in(");
		for(Menu m : allChildren){
			sb.append(m.getId()).append(",");;
		}
		sb.append(menu.getId());
		sb.append(")");
		String hqlDeleteAllChildren = sb.toString();
		System.out.println(hqlDeleteAllChildren);
		getSession().createQuery(hqlDeleteAllChildren).executeUpdate();
	}
	/**
	 * 查询指定类型和父菜单的子菜单,父菜单为null时查询一级菜单
	 */
	@Override
	public List<Menu> findSubMenuByMenutype(Long parent,MenuType menutype) {
		if(parent == null){
			return find(Restrictions.isNull("parent"),Restrictions.eq("menutype", menutype));
		}else{
			return find(Restrictions.eq("parent.id",parent));
		}
	}
	
	@Override
	public void updateVisibility(Long id, boolean visible){
		String hqlUpdateVisibility = "UPDATE Menu set visible =:visible where id=:id";
		getSession().createQuery(hqlUpdateVisibility)
				.setBoolean("visible", visible)
				.setLong("id", id)
				.executeUpdate();
		List<Menu> subMenus = findSubMenuByMenutype(id, null);
		for(Menu m : subMenus){
			updateVisibility(m.getId(), visible);
		}
	}
	
	private void findAllChildren(Long parent, MenuType menutype, List<Menu> list){
		List<Menu> directChildren = findSubMenuByMenutype(parent, menutype);
		list.addAll(directChildren);
		for(Menu m : directChildren){
			findAllChildren(m.getId(), m.getMenutype(), list);
		}
	}

}
